home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_075 / comm / wxmdmrecv.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  300 lines

  1. /* Comm WXMODEM receive file routines */
  2. #define  WXMDMRECV 1
  3. #include "globals.h"
  4. #include <fcntl.h>
  5.  
  6. extern  int WXch(), timedch();
  7. extern  void  send_proto(), emits_rx();
  8. extern  int   readchar();
  9.  
  10. static  short   eotflg, NAKsent, dirty;
  11. static  int     index, errsect, naks;
  12.  
  13. WXmodem_rec(file)
  14. UBYTE *file;
  15. {
  16.    unsigned crchi, crclo, sect, comp;
  17.    int ch, secerrs;
  18.    unsigned count;
  19.  
  20.    void chop_file();
  21.    ULONG  bytes;
  22.  
  23.    secerrs = errsect = naks = index = bytes = 0;
  24.    sector = 1;
  25.    cancel = eotflg = abort = dirty = FALSE;
  26.    
  27.    while(secerrs < RETRYMAX)
  28.    {
  29.       if(abort)                            /* keyboard abort (ESC) */
  30.       {
  31.          abortxfer();
  32.          return FALSE;
  33.       }
  34.  
  35.       if(cancel)                           /* remote sent CAN */
  36.       {
  37.          send_proto(ACK);
  38.          chop_file(index); close( fd );
  39.          if(( ch = timedch(5)) == CAN)
  40.             send_proto(ACK);
  41.          return TRUE;
  42.       }
  43. /* start of block */
  44.       do {                                 /* look for SYN/CAN/EOT */
  45.          ch = timedch(10);
  46.          if( ch == ERROR )
  47.          {
  48.             secerrs++;
  49.             send_proto(NAK); send_proto(errsect & 3);
  50.          }
  51.          if( (secerrs > RETRYMAX) || abort || cancel)
  52.          {
  53.             abortxfer();
  54.             return FALSE;
  55.          }
  56.          if(ch == EOT)
  57.          {
  58.              send_proto(NAK);
  59.              ch = timedch(5);
  60.              if(ch == EOT || ch == ERROR)
  61.              {
  62.                 send_proto(ACK);
  63.                 chop_file(index);  close( fd );
  64.                 return TRUE;
  65.              }
  66.          }
  67.       } while (ch != SYN);
  68.  
  69. /* got one SYN character -- gobble up the others */
  70.       while((ch = timedch(10)) == SYN)  ;
  71.  
  72. /* we got a non SYN character
  73.    if SOH, then we have a block, if not...who knows, so start over again
  74. */
  75.       if(ch != SOH)  continue;
  76.  
  77. /* block number and compliment */
  78.       sect = WXch(10);  emit_rx_protocol((UBYTE)sect);
  79.       comp = WXch(10);  emit_rx_protocol((UBYTE)comp);
  80.  
  81.       if( sect == ERROR || comp == ERROR)
  82.       {
  83.          Nak();
  84.          continue;
  85.       }
  86.  
  87. /* start of data
  88.       clear out the last block and start a new one
  89. */
  90.       if(dirty)
  91.       {
  92.          movmem(xbuffer,&diskbuff[index++ * SECSIZ],SECSIZ);
  93.          dirty = FALSE;
  94.       }
  95.  
  96.       crc = count = 0;
  97.       while( count < SECSIZ )
  98.       {
  99.          ch = WXch(10);
  100.          if( ch == ERROR ) break;
  101.          do_crc(ch);
  102.          xbuffer[ count++ ] = ch;
  103.          if(viewflg)
  104.             emit_vw(ch);
  105.       }
  106.  
  107.       if( ch == ERROR )
  108.       {
  109.          Nak();
  110.          continue;
  111.       }
  112.  
  113. /* first CRC byte */
  114.       if((crchi = WXch(10)) == ERROR)
  115.       {
  116.          Nak();
  117.          continue;
  118.       }
  119.       do_crc(crchi);
  120.  
  121. /* second CRC byte */
  122.       if((crclo = WXch(10)) == ERROR)
  123.       {
  124.          Nak();
  125.          continue;
  126.       }
  127.  
  128. /* see if checksum is valid */
  129.       if(!verify_checksum( crclo ))
  130.       {
  131.         emits_rx("  Checksum error\n");
  132.         Nak();
  133.         secerrs++;
  134.         status(file,bytes,naks,errsect);
  135.         continue;
  136.       }
  137.  
  138. /* does the block number match the compliment? */
  139.       if((UBYTE)sect != (UBYTE)~comp)
  140.       {
  141.          Nak(); secerrs++;
  142.          continue;      /* no: this isn't a real block! */
  143.       }
  144.  
  145. /* if this isn't the sector we're waiting for, try again */
  146.       if( (UBYTE)sect != (UBYTE)sector )
  147.       {
  148.          Nak();
  149.          continue;
  150.       }
  151.  
  152. /* otherwise, this must be a good sector and it must have good data,
  153.      so ACK it
  154. */
  155.     Ack(sect);
  156.     NAKsent = FALSE;
  157.     secerrs = 0;
  158.     sprintf(sbuff,"\rReceived block %d",sector);
  159.     emits_rx(sbuff);
  160.  
  161. /* accept the sector */
  162.     sector++;  dirty = TRUE;  bytes += SECSIZ;
  163.     status(file,bytes,naks,errsect);
  164.  
  165.     if(index == numbufs)
  166.     {
  167.       sendchar(XOFF);
  168.       if(write(fd,diskbuff,numbufs * SECSIZ) != numbufs * SECSIZ)
  169.       {
  170.          emits_rx("\nERROR writing to file\n");
  171.          abortxfer();
  172.          return FALSE;
  173.       }
  174.       index = 0;
  175.       sendchar(XON);
  176.     }
  177.   }
  178.   abortxfer();
  179.   return FALSE;
  180. }
  181.  
  182. /* send ACK */
  183. Ack(sect)
  184. int sect;
  185. {
  186.    send_proto(ACK);
  187.    send_proto(sect & 3);
  188. }
  189.  
  190. /* Send NAK unless we've already done so */
  191. Nak()
  192. {
  193.    if(!NAKsent)
  194.    {
  195.       send_proto(NAK);
  196.       send_proto(sector & 3);
  197.       errsect = sector;
  198.       NAKsent = TRUE;
  199.    }
  200.    naks++;
  201. }
  202.  
  203. timedch(time)
  204. int time;
  205. {
  206.    int ch;
  207.  
  208.    Process_window_event();
  209.    if(abort) return ERROR;
  210.  
  211.    ch = readchar(time,0);
  212.    if(ch == TIMEOUT)  return ERROR;
  213.  
  214.    emit_rx_protocol(ch);
  215.    return ch;
  216. }
  217.  
  218. WXch(time)
  219. int time;
  220. {
  221.    int gotdle,ch;
  222.  
  223.    gotdle = 0;
  224.  
  225.    Process_window_event();
  226.    if(abort) return ERROR;
  227.  
  228.    while(TRUE)
  229.    {
  230.       ch = readchar(time,0);
  231.       if(ch == TIMEOUT)  return ERROR;
  232.       switch (ch)
  233.       {
  234.          case DLE:
  235.                     gotdle = 64;
  236.                     continue;
  237.          case SYN:
  238.                     return ERROR;
  239.          default:
  240.                     return (ch ^ gotdle);
  241.       }
  242.    }
  243. }
  244.  
  245. abortxfer()
  246. {
  247.    int ch;
  248.  
  249.    sendchar(XOFF);
  250.    chop_file(index);
  251.    sendchar(XON);
  252.    send_proto(CAN);   send_proto(CAN);   send_proto(CAN);
  253.  
  254.    if(waitcan() == TRUE)
  255.       return TRUE;
  256.    return FALSE;
  257. }
  258.  
  259. waitcan()
  260. {
  261.    int ch,err;
  262.  
  263.    err = 0;
  264.    emits_rx("\nAborting...Wait...\n");
  265.    while (readchar(2,0) != TIMEOUT)
  266.       ;
  267.  
  268.    send_proto(CAN); send_proto(CAN);
  269.    ch = readchar(5,0);   ch = readchar(5,0);
  270.  
  271.    do {
  272.      if(err++ == 3) break;
  273.      send_proto(ACK);
  274.      emits_rx("Sending abort...\n");
  275.      Delay(50L);
  276.      send_proto(CAN); send_proto(CAN);
  277.      ch = readchar(3,0);
  278.    }  while( ch != CAN );
  279.  
  280.    send_proto(ACK);
  281.    return TRUE;
  282. }
  283.  
  284. sendWs()
  285. {
  286.    int ch,err;
  287.    err = 0;
  288.    send_proto('W');
  289.    do {
  290.       ch = timedch(3);
  291.       if(ch == SYN)
  292.          return TRUE;
  293.       if(ch == ERROR)
  294.          send_proto('W');
  295.    } while ( err++ < 3 );
  296.    return FALSE;
  297. }
  298.  
  299.  
  300.